Read image as a variable in R/Python. For R, you need to install “jpeg” package to read image into avariable. The variable you obtain is an array with three dimensions (suppose you read image to a variable “img”, try running “str(img)” command to see the structure of the variable. The size of the array should be 512 x 512 x 3 for the three dimensions). If you prefer Python, please find the appropriate module for this task.
library(jpeg)
getwd()
## [1] "C:/Users/Sinan/Desktop"
setwd("C:/Users/Sinan/Desktop")
img<-readJPEG("surfacenew.jpg")
str(img)
## num [1:512, 1:512, 1:3] 0.416 0.325 0.435 0.38 0.443 ...
What is the structure of the variable that stores the image? What is the dimension?
dim(img)
## [1] 512 512 3
The structure of the variable that stores the image is large array
#a-)
plot(1:2, type='n')
rasterImage(img, 1, 1, 2, 2)
R_channel<-matrix(img[ , , 1], 512, 512)
G_channel<-matrix(img[ , , 2], 512, 512)
B_channel<-matrix(img[ , , 3], 512, 512)
par(mfrow = c(1,3))
image(R_channel)
image(G_channel)
image(B_channel)
For each channel, take the average of the columns and plot the average as a line plot for each channel on a single plot.
avr_red<-(colSums(R_channel))/512
avr_green<-(colSums(G_channel))/512
avr_blue<-(colSums(B_channel))/512
plot(avr_red, type="l", col="red",ylim = range(0.35,0.67))
lines(avr_green, col="green")
lines(avr_blue, col="blue")
For each channel, subtract one half of the image from the other half (choice of halves is up to you but cropping the image vertically/horizontally into two parts make more sense) and display the new image.
halfred<-R_channel[ ,1:256]
half2red<-R_channel[ ,512:257]
image(halfred)
image(half2red)
red_new<-abs(halfred-half2red)
halfgreen<-G_channel[ ,1:256]
half2green<-G_channel[ ,512:257]
image(halfgreen)
image(half2green)
green_new<-abs(halfgreen-half2green)
halfblue<-B_channel[ ,1:256]
half2blue<-B_channel[ ,512:257]
image(halfblue)
image(half2blue)
blue_new<-abs(halfblue-half2blue)
newimg<-img[1:512,257:512,1:3]
newimg<-red_new
newimg<-green_new
newimg<-blue_new
plot(1:2, type='n')
rasterImage(newimg, 1, 1, 2, 2)
Apply median filtering to each channel of the image with the following window sizes, display the images (as a color image like in part 2-a) and discuss about the effect of window size based on your observations: a) 5x5
library("EBImage")
median_5<-medianFilter(img,5)
plot(1:2, type='n')
rasterImage(median_5, 1, 1, 2, 2)
median_11<-medianFilter(img,11)
plot(1:2, type='n')
rasterImage(median_11, 1, 1, 2, 2)
median_31<-medianFilter(img,31)
plot(1:2, type='n')
rasterImage(median_31, 1, 1, 2, 2)
Before working on the tasks, please transform your color image to a greyscale one using an image editor. The other option is to use some package/module to perform the transformation. You will be working on greyscale images for the following tasks:
require(stats)
library("imager")
## Loading required package: magrittr
##
## Attaching package: 'imager'
## The following object is masked from 'package:magrittr':
##
## add
## The following objects are masked from 'package:EBImage':
##
## channel, dilate, display, erode, resize, watershed
## The following objects are masked from 'package:stats':
##
## convolve, spectrum
## The following object is masked from 'package:graphics':
##
## frame
## The following object is masked from 'package:base':
##
## save.image
library(ggplot2)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following object is masked from 'package:EBImage':
##
## combine
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library("EBImage")
im <- load.image('surfacenew.jpg')
plot(im)
img_g<-grayscale(im)
plot(img_g)
Suppose we are interested in the pixel value distribution of our image. Draw the histogram of the pixel values. Provide an appropriate probability distribution that fits well to the shape you observe
pixel_for_dim<- as.data.frame(img_g)
pixels<-pixel_for_dim[,3]
hist(pixels) #Normal Distribution
We can see that pixel values are distributed with normal distribution.
Assume that pixel values are following the distribution you have proposed in the previous task. Estimate the parameters using the data.
#mean median variance and mode values
mean(pixels) #0.5687696
## [1] 0.5687696
median(pixels)
## [1] 0.5617647
var(pixels)
## [1] 0.01232743
sqrt(var(pixels))
## [1] 0.111029
getmode <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
getmode(pixels)
## [1] 0.5895686
Let’s say the pixel values follow the distribution you proposed and its parameters are equal to what you have estimated in part 2. Identify the pixels that are out of the 0.001 probability limits. In other words, find a lower and upper bound that leave 0.001 of the observations on the smaller and large side of the distribution respectively. Pixels that are out of these bounds should be identified. After finding those pixels, change the value of these pixels to zero (i.e. black color). Display the new image and original image in a plot. What are your observations? Comment on your findings.
sum1<-0
sum2<-0
#262144*0.001 =263
quantile(pixels, 0.001) #0.2873333
## 0.1%
## 0.2873333
quantile(pixels, 0.999) #0.8824314
## 99.9%
## 0.8824314
By using for loops,We can see how many pixels those are out of the lower and upper bounds
new_pixels<-pixel_for_dim
for (i in c(1:262144)){
if (new_pixels[,3][i]<=0.2873333){
sum1<-sum1+1
}
}
sum1 #262
## [1] 262
for (i in c(1:262144)){
if (new_pixels[,3][i]>=0.8824314){
sum2<-sum2+1
}
}
sum2 #258
## [1] 258
Pixels that are out of these bounds are identified and after finding those pixels,we changed the value of these pixels to zero.
for (i in c(1:262144)){
if (new_pixels[,3][i]>=0.8824314){
new_pixels[,3][i]=0
}
else if (new_pixels[,3][i]<=0.2873333){
new_pixels[,3][i]=0
}
}
Display the new image and original image in a plot.
#total
blacked_pixels<-new_pixels[,3] %>% as.cimg(dim=dim(img_g))
par(mfrow = c(1,2))
plot(1:2, type='n')
rasterImage(img_g, 1, 1, 2, 2)
plot(1:2, type='n')
rasterImage(blacked_pixels, 1, 1, 2, 2)
a=c(1,2)
Suppose we would like to perform the same operation on the patches of images (i.e. windows of certain size). When local structures are important, performing image operations on the patches might be important. Assume that your window size is 51x51 and you repeated what you have done in the first three tasks. Note that you do not need to draw each patch as requested in the previous task (i.e. task 3) but you are expected to mark the pixels for every patch. After finding those pixels, change the value of these pixels to zero (i.e. black color). Display the new image and original image in a plot. What are your observations? Comment on your findings
new_windows<-img_g
hist_data_of_windows<-array(0,dim = c(10,10,2601))
mean_of_windows<-array(0,dim = c(10,10))
variance_of_windows<-array(0,dim = c(10,10))
sum_of_blacked<-0
By using for loop,We found those pixels which are out of the lower and the upper bounds and changed the value of those pixels to zero
for (k in c(1:10)){
for(l in c(1:10)){
kleft<-(1+(51*k)-51)
kright<-(51*k)
lleft<-(1+(51*l)-51)
lright<-(51*l)
image_new<-new_windows[kleft:kright,lleft:lright]
low<-quantile(image_new, 0.001)
high<-quantile(image_new, 0.999)
for(i in c(1:2601)){
if(image_new[i]<= low){
image_new[i]=0
sum_of_blacked=sum_of_blacked+1
}
else if(image_new[i]>=high){
image_new[i]=0
sum_of_blacked=sum_of_blacked+1
}
}
mean_of_windows[k,l]=mean(image_new)
variance_of_windows[k,l]=var(as.data.frame(as.cimg(image_new))[,3])
hist_data_of_windows[k,l,]=image_new
new_windows[kleft:kright,lleft:lright]=image_new
}
}
We can see the statical parameters for each patches.
mean_of_windows
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 0.4536502 0.5369130 0.5796631 0.6026657 0.5928173 0.5300282
## [2,] 0.5730905 0.6000424 0.6130711 0.6169793 0.6012252 0.5424018
## [3,] 0.6360627 0.6400365 0.6428677 0.6183437 0.6183898 0.5707447
## [4,] 0.6558161 0.6645644 0.6552727 0.6314927 0.6309769 0.6022510
## [5,] 0.6591475 0.6651963 0.6563668 0.6214974 0.6192300 0.6121613
## [6,] 0.6513381 0.6417535 0.6468546 0.6176586 0.6026811 0.5848822
## [7,] 0.6432607 0.6415564 0.6364553 0.5980820 0.5850901 0.5499009
## [8,] 0.6448071 0.6331480 0.6311566 0.6196913 0.5728600 0.5254475
## [9,] 0.6511073 0.6356703 0.6359504 0.6235606 0.5687706 0.5056660
## [10,] 0.6392355 0.6208403 0.6149427 0.6115081 0.5570538 0.4791871
## [,7] [,8] [,9] [,10]
## [1,] 0.4867436 0.4534441 0.4316404 0.4099351
## [2,] 0.5062882 0.4852582 0.4751964 0.4699974
## [3,] 0.5364974 0.5119329 0.5009312 0.4925288
## [4,] 0.5686598 0.5405348 0.5232183 0.5031481
## [5,] 0.5871729 0.5608585 0.5337978 0.5131959
## [6,] 0.5602504 0.5590815 0.5457760 0.5197166
## [7,] 0.5360766 0.5308694 0.5362830 0.5291982
## [8,] 0.5096204 0.5033954 0.5140189 0.5183851
## [9,] 0.4934741 0.4902470 0.4946666 0.4996402
## [10,] 0.4720435 0.4772205 0.4835979 0.5028085
variance_of_windows
## [,1] [,2] [,3] [,4] [,5]
## [1,] 0.007478093 0.007568243 0.010073346 0.010882885 0.010213491
## [2,] 0.008506050 0.010580732 0.010807261 0.011032389 0.011941103
## [3,] 0.009887148 0.011275832 0.010864505 0.011949368 0.011646832
## [4,] 0.010730668 0.011565894 0.011146354 0.012589497 0.010860254
## [5,] 0.009531552 0.011094684 0.011968779 0.012067554 0.010967690
## [6,] 0.010866122 0.010596369 0.010713057 0.012015996 0.010876443
## [7,] 0.011858770 0.011650159 0.010909065 0.010510934 0.009994307
## [8,] 0.010482308 0.011130911 0.010585349 0.011496517 0.010088679
## [9,] 0.009116449 0.011321359 0.010234911 0.010758585 0.009636413
## [10,] 0.008420648 0.010195615 0.008989119 0.009743634 0.007770781
## [,6] [,7] [,8] [,9] [,10]
## [1,] 0.011230611 0.009081092 0.008039115 0.006718396 0.003819788
## [2,] 0.011328456 0.010079535 0.008698880 0.009093699 0.006165004
## [3,] 0.011397307 0.010125201 0.008683483 0.008113933 0.006492343
## [4,] 0.010657355 0.010348721 0.008718676 0.008011745 0.006360706
## [5,] 0.010616286 0.009596669 0.008152012 0.007943158 0.006327098
## [6,] 0.009990610 0.009523852 0.007792675 0.007287870 0.006204988
## [7,] 0.008927446 0.007864726 0.006745462 0.006341339 0.005247071
## [8,] 0.007371611 0.006780475 0.005293861 0.005059378 0.004694195
## [9,] 0.006723042 0.005147440 0.004353098 0.003741405 0.003243599
## [10,] 0.004883835 0.004478291 0.003496359 0.003000511 0.002707083
sum_of_blacked #624
## [1] 624
To see the histograms of each 100 patches.
for(i in c(1:10)){
par(mfrow= c(2,5))
for (j in c(1:10)) {
hist(hist_data_of_windows[i,j,])
}
}
Displaying the new image and original image in a plot
par(mfrow = c(1,2))
plot(1:2, type='n')
rasterImage(img_g, 1, 1, 2, 2)
plot(1:2, type='n')
rasterImage(new_windows, 1, 1, 2, 2)